﻿using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Threading.Tasks;
using WalkingTec.Mvvm.Core;
using WalkingTec.Mvvm.Mvc;
using WalkingTec.Mvvm.Core.Extensions;
using System.Linq;
using System.Collections.Generic;
using TyMES.Model.Record;
using TyMES.ViewModel.Record.ProduceDataRecordVMs;
using TyMES.Model;
using TyMES.Services;
using Azure;
using TyMES.Communication;
using Newtonsoft.Json;
using static TyMES.Record.Controllers.PersonLayOffRecordController;
using TyMES.TemporaryClass;
using TyMES.Model.BaseInformation;
using Microsoft.Extensions.Configuration;
using static TyMES.Services.PassStationService;
using TyMES.Communication.Request;
using NPOI.SS.Formula.Functions;
using Jint.Native;

namespace TyMES.Record.Controllers
{
    [AuthorizeJwtWithCookie]
    [ActionDescription("_Model.ProduceDataRecord")]
    [ApiController]
    [Route("/api/Record/ProduceDataRecord")]
    public partial class ProduceDataRecordController : BaseApiController
    {
        private ProductDataService _productDataService;
        private readonly IConfiguration _configuration;
        private string factoryCode;
        private readonly HttpService _httpService;
        private readonly PassStationService passStationService;
        private readonly SPCService spcService;
        private string mesIP;
        private string mesPort;
        private string _LineCode;

        public ProduceDataRecordController(ProductDataService productDataService, IConfiguration configuration, HttpService httpService, PassStationService passStationService, SPCService spcService)
        {
            _configuration = configuration;
            this._productDataService = productDataService;
            factoryCode = configuration["FactoryCode"];
            this.mesIP = configuration["MESIP"];
            this.mesPort = configuration["MESPORT"];
            this._LineCode = configuration["LineCode"];
            _httpService = httpService;
            this.passStationService = passStationService;
            this.spcService = spcService;
            
    }

        [ActionDescription("Sys.Get")]
        [HttpGet("{id}")]
        public IActionResult Get(string id)
        {
            var vm = Wtm.CreateVM<ProduceDataRecordVM>(id);
            return Ok(vm);
        }

        [ActionDescription("Sys.Create")]
        [HttpPost("[action]")]
        public async Task<IActionResult> Create(ProduceDataRecordVM vm)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState.GetErrorJson());
            }
            else
            {
                await vm.DoAddAsync();

                if (!ModelState.IsValid)
                {
                    return BadRequest(ModelState.GetErrorJson());
                }
                else
                {
                    return Ok(vm.Entity);
                }
            }

        }


        [AllRights]
        [HttpPost("ScadaAdd")]
        public async Task<ActionResult> ScadaAdd(Producepara.DataPacket record1)
        {
            ProduceDataRecord record =await MapToProduceRecord(record1);
            var linecode = DC.Set<TrayBindVSN>().SingleOrDefault(x => x.VSN == record.SN)?.LineCode;
            StationLogRecord stationLog = new StationLogRecord();
           
            stationLog.StationCode = record.StationCode;
            stationLog.LineCode = _LineCode;
            stationLog.Date_Time = DateTime.Now;
            stationLog.CreateTime = DateTime.Now;
            try
            {
                char[] delimiterChars = { '*' };
                string ParaCodes =string.Empty;

                var CLStation = DC.Set<CustomConfig>().Where(x=>x.customProperty== "CLStationCode").FirstOrDefault()?.propertyValue;
                if (CLStation.Contains(record.StationCode))
                {
                    //测漏工位数据需要特殊处理
                    string TZCode = record.SN.Split(delimiterChars)[0];
                    string LWM1 = record.SN.Split(delimiterChars)[1];
                    string LWM2 = record.SN.Split(delimiterChars)[2];
                    var backupSN = await passStationService.GetCSSNByTZCode(TZCode, "",record.StationCode);
                    record.SN = backupSN.Mesg;
                    record.Data = LWM1+"*"+LWM2 + "*"+ record.Data;
                    record.DataName = "零位码1" + "*" + "零位码2" + "*" + record.DataName;
                    for (int i = 0;i< record.DataName.Split(delimiterChars).Length; i++)
                    {
                        ParaCodes += "para" + i.ToString()+"*";
                    }
                    ParaCodes = ParaCodes.Substring(0,ParaCodes.Length-1);
                }
                else
                {
                    var producedataname = DC.Set<ProduceDataType>().Where(x => x.stationCode == record.StationCode).FirstOrDefault();

                    //2-OP4260-0工位传的是电机码
                    if (record.StationCode == "2-OP4260-0")
                    {
                        var backupSN = await passStationService.GetCSSNByTZCode(record.SN, "", record.StationCode);
                        record.SN = backupSN.Mesg;
                    }

                    if (producedataname == null)
                    {
                        stationLog.LogType = "bad";
                        stationLog.Log = "生产数据上传失败,工位" + record.StationCode + "未在生产数据信息表维护生产数据名";
                        addstationlog(stationLog);

                        record.SqlFlag = false;
                        addproducedatalog(record);
                        //噪音房由于上传数据长度不固定，特殊处理
                        if(record.StationCode.Contains("2-OP4170"))
                            return Ok(new ResponseBase(true, record.StationCode + "此站未在生产数据信息表维护生产数据名"));
                        return Ok(new ResponseBase(false, record.StationCode + "此站未在生产数据信息表维护生产数据名"));
                    }
                    record.DataName = producedataname.dataType;
                    ParaCodes = producedataname.nameTable;
                }


                

                string[] datadescripe = record.DataName.Split(delimiterChars);
                string[] dataname = ParaCodes.Split(delimiterChars);
                ProductDataRequest request = new ProductDataRequest();
                request.data = new List<ProductData>();
                //按*分割数据
                
                string[] data = record.Data.Split(delimiterChars);
                string[] result = record.Result.Split(delimiterChars);
                var traybindorder = DC.Set<TrayBindVSN>().Where(x => x.VSN == record.SN).ToList();
                if (traybindorder.Count > 0)
                {
                    //根据工单号去获取工单信息
                    List<Order_Model> mOrders = DC.Set<Order_Model>().Where(x => x.OrderCode == traybindorder[0].OrderCode).ToList();
                    if (data.Length < dataname.Length)
                    {
                        await passStationService.stationlogadd(stationLog, stationLog.LineCode, stationLog.StationCode, record.SN, "bad", $"上传生产数据[{record.Data}]数据长度小于生产数据类型管理中维护的数据应有字段长度，请检查");
                        addproducedatalog(record);
                        return Ok(new ResponseBase(false, $"上传生产数据[{record.Data}]数据长度小于生产数据类型管理中维护的数据应有字段长度，请检查"));
                    }
                    for (int i = 0; i < dataname.Length; i++)
                    {
                        if (dataname[i] == "0")
                            continue;

                        ProductData productData = new ProductData();
                        productData.factoryCode = factoryCode;
                        productData.lineCode = _LineCode;
                        productData.stationCode = record.StationCode;
                        productData.materialCode = mOrders[0].MaterialCode;
                        productData.materialVersion = mOrders[0].MaterialVersion;
                        productData.snNumber = record.SN;
                        productData.operationCode = record.StationCode;//暂时用工位号替代，后续需更改
                        productData.paramCode = dataname[i];
                        productData.paramName = datadescripe[i];
                        productData.standardValue = "";
                        productData.paramRange1 = "";
                        productData.paramRange2 = "";
                        productData.realValue = data[i];
                        productData.isQualified = "0";
                        productData.checkStarttime = "";
                        productData.checkEndtime = "";
                        productData.dataStatus = "0";
                        productData.addTime = "";
                        productData.addUserId = "";
                        productData.editUserId = "";
                        productData.editTime = "";
                        productData.spare1 = "";
                        productData.spare2 = "";
                        productData.spare3 = "";
                        productData.spare4 = "";
                        productData.addUserCode = "";
                        productData.machineCode = "";
                        request.data.Add(productData);
                    }
                    request.factoryCode = factoryCode;
                    request.serviceId = "Quality001_inspectiondata";
                    //泰国电驱先禁用Quality001_inspectiondata
                    //string postdata = JsonConvert.SerializeObject(request);
                    //string value = await _httpService.PostDataAsync("http://"+mesIP+":"+mesPort+"/api/base/Base_Information", postdata);
                    //responseMes response = JsonConvert.DeserializeObject<responseMes>(value);
                    //record.SqlFlag = false;
                    //if (response.code == "000000")
                    //{
                    //    stationLog.Log = record.SN + "生产数据上传Quality001_inspectiondata成功" +  ":" + response.data + ":" + response.mesg+"\n";
                    //}
                    //else
                    //{
                    //    stationLog.Log = record.SN + "生产数据上传Quality001_inspectiondata失败" +  ":" + response.data + ":" + response.mesg+"\n";
                    //}

                    var para006 = await passStationService.PostProductPara006(request);
                    if (para006.Success == true)
                    {
                        record.SqlFlag = true;
                        stationLog.LogType = "good";
                        stationLog.Log = stationLog.Log + "生产数据上传Product006_ProductParameters成功" + para006.Mesg;// +  ":" + response.data + ":" + response.mesg
                        addstationlog(stationLog);
                    }
                    else
                    {
                        stationLog.LogType = "bad";
                        stationLog.Log = stationLog.Log + "生产数据上传Product006_ProductParameters失败" + para006.Mesg;//+  ":" + response.data + ":" + response.mesg
                        addstationlog(stationLog);
                    }
                   addproducedatalog(record);
                }
                else
                {
                    //添加日志
                    stationLog.LogType = "bad";
                    stationLog.Log = "SN" + ":" + record.SN + "不存在对应的工单信息，请上传正确的SN";
                    addstationlog(stationLog);

                    record.SqlFlag = false;
                    addproducedatalog(record);
                }
            }
            catch (Exception ex)
            {
                stationLog.LogType = "bad";
                stationLog.Log = record.SN + ":" + ex.Message.ToString();
                addstationlog(stationLog);

                record.SqlFlag = false;
                addproducedatalog(record);
            }
            
            return  Ok(new ResponseBase(true, "已传入生产数据"));
        }


        
       
        public void addstationlog(StationLogRecord stationLog)
        {
            DC.Set<StationLogRecord>().Add(stationLog);
            DC.SaveChanges();
        }
        public void addproducedatalog(ProduceDataRecord record)
        {
            DC.Set<ProduceDataRecord>().Add(record);
            DC.SaveChanges();
        }

        public async Task< ProduceDataRecord> MapToProduceRecord(Producepara.DataPacket data)
        {

            ProduceDataRecord record =  new ProduceDataRecord();
            record.SN = data.SN;
            record.StationCode = data.StationCode;
            record.Data = data.Data;
            record.DataName = data.DataName;
            record.Result = data.Result;
            record.SqlFlag = data.SqlFlag;
            record.CreateTime = DateTime.Now;
            return record;
        }

        

        [ActionDescription("Sys.Edit")]
        [HttpPut("[action]")]
        public async Task<IActionResult> Edit(ProduceDataRecordVM vm)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState.GetErrorJson());
            }
            else
            {
                await vm.DoEditAsync(false);
                if (!ModelState.IsValid)
                {
                    return BadRequest(ModelState.GetErrorJson());
                }
                else
                {
                    return Ok(vm.Entity);
                }
            }
        }


        [HttpPost("BatchEdit")]
        [ActionDescription("Sys.BatchEdit")]
        public ActionResult BatchEdit(ProduceDataRecordBatchVM vm)
        {
            if (!ModelState.IsValid || !vm.DoBatchEdit())
            {
                return BadRequest(ModelState.GetErrorJson());
            }
            else
            {
                return Ok(vm.Ids.Count());
            }
        }

        [HttpPost("BatchDelete")]
        [ActionDescription("Sys.Delete")]
        public IActionResult BatchDelete(string[] ids)
        {
            var vm = Wtm.CreateVM<ProduceDataRecordBatchVM>();
            if (ids != null && ids.Count() > 0)
            {
                vm.Ids = ids;
            }
            else
            {
                return Ok();
            }
            if (!ModelState.IsValid || !vm.DoBatchDelete())
            {
                return BadRequest(ModelState.GetErrorJson());
            }
            else
            {
                return Ok(ids.Count());
            }
        }

        [ActionDescription("Sys.DownloadTemplate")]
        [HttpGet("GetExcelTemplate")]
        public IActionResult GetExcelTemplate()
        {
            var vm = Wtm.CreateVM<ProduceDataRecordImportVM>();
            var qs = new Dictionary<string, string>();
            foreach (var item in Request.Query.Keys)
            {
                qs.Add(item, Request.Query[item]);
            }
            vm.SetParms(qs);
            var data = vm.GenerateTemplate(out string fileName);
            return File(data, "application/vnd.ms-excel", fileName);
        }

        [ActionDescription("Sys.Import")]
        [HttpPost("Import")]
        public ActionResult Import(ProduceDataRecordImportVM vm)
        {

            if (vm.ErrorListVM.EntityList.Count > 0 || !vm.BatchSaveData())
            {
                return BadRequest(vm.GetErrorJson());
            }
            else
            {
                return Ok(vm.EntityList.Count);
            }
        }


        //[HttpPost("ScadaAdd")]
        public async Task<ActionResult> LKScadaAdd(ProduceDataRecord record)
        {
            string reslut = string.Empty;
            try
            {
                if (record.SN == "" ||record.SN ==null)
                {
                    return Ok(new ResponseBase(false, "Scada上传生产数据记录SN为空"));
                }
                var recordlist = _productDataService.MapFromLMESTemplate(record);
                foreach (var item in recordlist)
                {
                    if (item.Result == "NG") reslut += item.DataName + "NG";
                    await DC.Set<ProduceDataRecord>().AddAsync(item);
                }
                var topFiveRecords = DC.Set<ProduceDataRecord>()
                    .Where(x => x.SqlFlag != true)
                    .OrderByDescending(x => x.CreateTime)
                    .GroupBy(x => x.SN)
                    .Select(g => g.First())
                    .OrderByDescending(x => x.CreateTime)
                    .Take(5);

                foreach (var item in topFiveRecords)
                {
                    await _productDataService.UploadProductData2FMES(item.StationCode, item.SN);
                }
                //a?b:c;  a leftpoint b:c right ?fengefu expression.leftpoit=
                return reslut.Length>0? Ok(new ResponseBase(false, reslut)):Ok(new ResponseBase (true,"上传生产数据" + record.SN + "成功"));
            }
            catch (Exception ex)
            {
                return Ok(new ResponseBase(false, ex.ToString()));
            }


        }
        public class responseMes
        {
            public string code { get; set; }
            public bool success { get; set; }
            public bool fail { get; set; }
            public string mesg { get; set; }
            public string data { get; set; }
            public string time { get; set; }
        }

        public class ProductDataRequest
        {
            public List<ProductData> data { get; set; }
            public string serviceId { get; set; }
            public string factoryCode { get; set; }
        }

        public class ProductData
        {
            public string factoryCode { get; set; }
            public string lineCode { get; set; }
            public string stationCode { get; set; }
            public string materialCode { get; set; }
            public string materialVersion { get; set; }
            public string snNumber { get; set; }
            public string operationCode { get; set; }
            public string paramCode { get; set; }
            public string paramName { get; set; }
            public string standardValue { get; set; }
            public string paramRange1 { get; set; }
            public string paramRange2 { get; set; }
            public string realValue { get; set; }
            public string isQualified { get; set; }
            public string checkStarttime { get; set; }
            public string checkEndtime { get; set; }
            public string dataStatus { get; set; }
            public string addUserId { get; set; }
            public string addTime { get; set; }
            public string editUserId { get; set; }
            public string editTime { get; set; }
            public string spare1 { get; set; }
            public string spare2 { get; set; }
            public string spare3 { get; set; }
            public string spare4 { get; set; }
            public string addUserCode { get; set; }
            public string machineCode { get; set; }
        }



    }
}